package cn.tedu.csmall.product.service.impl;

import cn.tedu.csmall.product.ex.ServiceException;
import cn.tedu.csmall.product.mapper.AttributeMapper;
import cn.tedu.csmall.product.pojo.dto.AttributeAddNewDTO;
import cn.tedu.csmall.product.pojo.dto.AttributeUpdateDTO;
import cn.tedu.csmall.product.pojo.entity.Attribute;
import cn.tedu.csmall.product.pojo.vo.AttributeListVO;
import cn.tedu.csmall.product.pojo.vo.AttributeStandardVO;
import cn.tedu.csmall.product.repo.impl.AttributeRedisRepositoryImpl;
import cn.tedu.csmall.product.service.IAttributeService;
import cn.tedu.csmall.product.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * IAttributeService的实现类
 */
@Slf4j
@Service
public class AttributeServiceImpl implements IAttributeService {
    @Autowired
    AttributeMapper attributeMapper;
    @Autowired
    AttributeRedisRepositoryImpl repository;

    @Override
    public void addNew(AttributeAddNewDTO dto) {
        log.debug("开始处理添加属性业务,参数:{}",dto);
        //查询同一个模板属性下属性名称是否唯一
        int i = attributeMapper.countByNameAndTemplate(dto.getName(), dto.getTemplateId());
        if (i>0) {
            //是: 属性名称被占用, 添加失败
            String message = "属性名称被占用, 添加失败";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }
        //否: 属性名称未被占用, 可以添加
        Attribute attribute = new Attribute();
        log.debug("属性名称未被占用, 可以添加");
        BeanUtils.copyProperties(dto, attribute);
        i = attributeMapper.insert(attribute);
        if (i != 1) {
            String message = "属性添加失败, 服务器忙, 请稍后再试";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_INSERT, message);
        }
        log.debug("添加属性成功");
    }

    @Override
    public void deleteById(Long id) {
        log.debug("开始处理根据id删除属性业务,参数:{}",id);
        //判断属性数据是否存在
        AttributeStandardVO standardById = attributeMapper.getStandardById(id);
        if (standardById == null) {
            //数据不存在, 抛出异常, 删除失败
            String message = "删除失败, 数据不存在";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        //数据存在, 可以删除
        int i = attributeMapper.deleteById(id);
        //判断是否成功删除了数据
        if (i != 1) {
            String message = "属性删除失败, 服务器忙, 请稍后再试";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_INSERT, message);
        }
        log.debug("添加删除成功");
    }

    @Override
    public void updateById(AttributeUpdateDTO dto) {
        log.debug("开始处理修改属性详情业务, 参数:{}",dto);
        AttributeStandardVO standardById = attributeMapper.getStandardById(dto.getId());
        //判断该属性是否存在
        if (standardById == null) {
            //否: 不存在, 抛出异常, 修改失败
            String message = "修改失败, 尝试访问的属性不存在";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND ,message);
        }
        //是: 存在, 继续判断新的name是否与数据库已有的, 相同templateId的重复
        int i = attributeMapper.countByNameAndTemplate(dto.getName(), standardById.getTemplateId());
        if (i > 0) {
            //是: 对象重复, 抛出异常, 修改失败
            String message = "修改失败, 在同一模板下有重复的名字";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT ,message);
        }
        //否: 可以修改
        Attribute attribute = new Attribute();
        BeanUtils.copyProperties(dto, attribute);
        log.debug("开始修改属性详情,参数:{}",attribute);
        i = attributeMapper.updateById(attribute);
        if (i != 1) {
            String message = "属性修改失败, 服务器忙, 请稍后再试";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_INSERT, message);
        }
        log.debug("修改属性成功");
    }

    @Override
    public List<AttributeListVO> list() {
        log.debug("开始处理查询属性列表业务");
        return repository.list();
    }

    @Override
    public List<AttributeListVO> listAttributeByTemplateId(Long templateId) {
        log.debug("开始处理根据属性模板id查询属性业务,参数:{}",templateId);
        //判断属性模板id查询是否有对应的对象
        int i = attributeMapper.countByTemplateId(templateId);
        if (i == 0){
            //没有对应的对象, 抛出异常, 查询失败
            String message = "没有对应的对象, 查询失败";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        //存在对应的对象, 开始查询
        log.debug("存在对应的对象, 开始查询");
        List<AttributeListVO> list
                = attributeMapper.listAttributeByTemplateId(templateId);
        return list;
    }

    @Override
    public AttributeStandardVO getStandardById(Long id) {
        log.debug("开始处理查询属性模板详情业务,参数:{}",id);
        AttributeStandardVO vo = attributeMapper.getStandardById(id);
        if (vo == null) {
            String message = "属性模板数据不存在,查询失败";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        return vo;
    }

    @Override
    public void rebuildCache() {
        log.debug("准备删除Redis缓存中的属性数据...");
        repository.deleteAll();
        log.debug("删除Redis缓存中的属性数据完成");

        log.debug("准备从数据库中读取属性数据");
        List<AttributeListVO> list = list();
        log.debug("读取Redis缓存中的属性数据完成");

        log.debug("准备向Redis缓存中添加数据");
        repository.save(list);
        log.debug("向Redis缓存中添加属性数据完成");
    }
}
